import { Injectable, ComponentFactoryResolver, Injector, ApplicationRef, EventEmitter } from '@angular/core';
import { DomPortalHost, Portal, ComponentPortal } from '@angular/cdk/portal';

import { FeaturePropertyComponent } from './container/feature-property.component';
import { FeaturePropertyRef, FeaturePropertyOptionService } from './feature-property-ref.class';
import { FeaturePropertyOptions } from './feature-property.type';
import { Store } from '@ngrx/store';
import { State } from '../../../store';
import * as fromFeatureActoin from '../../store/actions/feature.action';


@Injectable()
export class FeaturePropertyService extends FeaturePropertyRef {

  private portalHost: DomPortalHost;
  private portal: ComponentPortal<FeaturePropertyComponent>;
  private afterClose$: EventEmitter<any> = new EventEmitter();
  private onCloseCallback: () => void;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private injector: Injector,
    private appRef: ApplicationRef,
    private store: Store<State>
  ) { 
    super();
    this.afterClose$.subscribe(() => {
      this.close();
      this.store.dispatch(new fromFeatureActoin.FeatureSelected(null));
    });
  }

  create(outletElement: HTMLElement, options: FeaturePropertyOptions = {}): FeaturePropertyRef {
    if(!this.portalHost) {
      this.createProtalHost(outletElement);
    }
    if(this.portal) {

    }
    this.createProtal(options);
    return this;
  }

  close(): void {
    if(this.portalHost) {
      this.portalHost.detach();
      this.portal = null;
      this.onCloseCallback && this.onCloseCallback();
    }
  }

  private createProtalHost(outletElement?: HTMLElement): void {
    if(!outletElement) {
      outletElement = document.querySelector('body');
    }
    this.portalHost = new DomPortalHost(
      outletElement,
      this.componentFactoryResolver,
      this.appRef,
      this.injector
    );
  } 

  private createProtal(options: FeaturePropertyOptions): void {
    const injector = Injector.create([{
      provide: FeaturePropertyOptionService,
      useValue: {
        ...options,
        close$: this.afterClose$
      }
    }]);
    this.portal = new ComponentPortal(FeaturePropertyComponent, null, injector);
    this.portalHost.attach(this.portal);
  }

}
